<?php
/**
 * Třída slouží pro šifrování vstupů
 */

class crypt {
   private static $metoda;
   private static $salt;
   private static $blok_length;
   
   /**
    * Vrací zahešovaný vstup o délce heše metody
    * @param string $vstup
    * @return string
    */
   public static function hmac_hash($vstup, $salt, $metoda = 'sha1') {
      if (function_exists('hash') && is_string($metoda) && in_array($metoda, hash_algos()))
      {
          self::$metoda = $metoda;
          self::$salt = $salt;
          self::$blok_length = strlen(hash(self::$metoda, self::$salt));
      }
      else
      {
          self::$metoda = false;
          self::$salt = $salt;
          self::$blok_length = strlen(sha1(self::$salt));
      }
      $k_salt = self::get_key();
      $k_opad = self::get_opad($k_salt);
      $k_ipad = self::get_ipad($k_salt);
      
      if(self::$metoda === false)
      {
         return sha1($k_opad . pack("H*", sha1($k_ipad . $vstup)));
      }
      else
      {
         return hash(self::$metoda, $k_opad . pack("H*", hash(self::$metoda, $k_ipad . $vstup)));
      }
   }
   
   public static function get_algos(){
      if(function_exists('hash_algos'))
      {
         return hash_algos();
      }
   }


   /**
    * PRIVATNÍ metoda pro získání klíče ze soli
    * @param enum $metoda ['md5','sha1']
    * @param int $delka_bloku
    * @return string
    */
   private static function get_key() {
      $klic = self::$salt;
      $metoda = self::$metoda;
      $delka_bloku = self::$blok_length;
      
      if(self::$metoda === false)
      {         
         if (strlen($klic) > $delka_bloku) 
         {
            return pack("H*", sha1($klic));
         }
         else
         {      
            return str_pad($klic, $delka_bloku, chr(0x00));         
         }          
      }
      else
      {       
         if (strlen($klic) > $delka_bloku) 
         {
            return pack("H*", hash($metoda, $klic));
         }
         else
         {      
            return str_pad($klic, $delka_bloku, chr(0x00));         
         } 
      }     
   }

   /**
    * PRIVATNÍ metoda pro získání jedné z části potřebné pro metodu hmac
    * @param string $klic 
    * @param int $delka_bloku
    * @return string
    */
   private static function get_ipad($klic) {
      return $klic xor str_repeat(chr(0x36), self::$blok_length);
      
   }
   
   /**
    * PRIVATNÍ metoda pro získání jedné z části potřebné pro metodu hmac
    * @param string $klic 
    * @param int $delka_bloku
    * @return string
    */
   private static function get_opad($klic) {
      return $klic xor str_repeat(chr(0x5c), self::$blok_length);      
   }
}

class sifruj {
   private static $salt = 's19wor9d3s_o.f_d8e8stin91y';
   
   /**
    * Vrací zahešovaný vstup o délce heše md5 (32 znaků)
    * @param string $vstup
    * @return string
    */
   public static function hmac_md5($vstup) {
      $metoda = 'md5';
      $md5_len = strlen($metoda(self::$salt));
      $k_salt = self::get_key($metoda, $md5_len);
      $k_opad = self::get_opad($k_salt, $md5_len);
      $k_ipad = self::get_ipad($k_salt, $md5_len);
      return $metoda($k_opad . pack("H*", $metoda($k_ipad . $vstup)));   
   }
   
   /**
    * Vrací zahešovaný vstup o délce heše sha1 (40 znaků)
    * @param string $vstup
    * @return string
    */
   public static function hmac_sha1($vstup) {
      $metoda = 'sha1';
      $sha1_len = strlen($metoda(self::$salt));
      $k_salt = self::get_key($metoda, $sha1_len);
      $k_opad = self::get_opad($k_salt, $sha1_len);
      $k_ipad = self::get_ipad($k_salt, $sha1_len);
      return $metoda($k_opad . pack("H*", $metoda($k_ipad . $vstup)));      
   }
   
   /**
    * PRIVATNÍ metoda pro získání klíče ze soli
    * @param enum $metoda ['md5','sha1']
    * @param int $delka_bloku
    * @return string
    */
   private static function get_key($metoda, $delka_bloku) {
      $klic = self::$salt;
      if (strlen($klic) > $delka_bloku) 
      {
         return pack("H*", $metoda($klic));
      }
      else
      {      
         return str_pad($klic, $delka_bloku, chr(0x00));         
      }      
   }

   /**
    * PRIVATNÍ metoda pro získání jedné z části potřebné pro metodu hmac
    * @param string $klic 
    * @param int $delka_bloku
    * @return string
    */
   private static function get_ipad($klic, $delka_bloku) {
      return $klic xor str_repeat(chr(0x36), $delka_bloku);
      
   }
   
   /**
    * PRIVATNÍ metoda pro získání jedné z části potřebné pro metodu hmac
    * @param string $klic 
    * @param int $delka_bloku
    * @return string
    */
   private static function get_opad($klic, $delka_bloku) {
      return $klic xor str_repeat(chr(0x5c), $delka_bloku);      
   }
}
?>